package com.rc.web.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.rc.common.constant.OrderStatusType;
import com.rc.pojo.po.*;
import com.rc.pojo.vo.dashboard.*;
import com.rc.pojo.vo.order.FirstFiveMonthOrderVO;
import com.rc.web.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.time.temporal.TemporalAdjusters;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 仪表盘服务实现类
 * 提供仪表盘相关数据的统计和展示功能
 */
@Service
@RequiredArgsConstructor
public class DashboardServiceImpl implements DashboardService {
    // 植物服务
    private final PlantService plantService;
    // 园区服务
    private final AreaService areaService;
    // 用户服务
    private final UserService userService;
    // 领养服务
    private final AdoptionService adoptionService;
    // 活动服务
    private final ActivityService activityService;
    // 订单服务
    private final OrderService orderService;
    // 消费者服务
    private final ConsumerService consumerService;
    // 农场服务
    private final FarmService farmService;

    /**
     * 获取植物分布情况
     * @return 植物分布VO列表
     */
    @Override
    public List<PlantDistributionVO> getPlantDistribution() {
        List<Plant> plantList = plantService.list();
        List<Area> areaList = areaService.list();
        // 植物id 和 园区列表映射
        Map<Long, List<Area>> plantAreaMap = areaList.stream()
                .collect(Collectors.groupingBy(Area::getPlantId));

        int totalArea = areaList.size();
        return plantList.stream()
                .map(plant -> {
                    int plantArea = plantAreaMap.getOrDefault(plant.getId(),List.of()).size();
                    // 计算占比
                    double value = 100.0 * plantArea / totalArea ;
                    return PlantDistributionVO.builder()
                            // 植物名称
                            .name(plant.getName())
                            // 该植物园区个数
                            .value(value)
                            .build();
                })
                .toList();
    }

    /**
     * 获取前五个月订单数据
     * @return 前五个月订单VO列表
     */
    @Override
    public List<FirstFiveMonthOrderVO> getfirstFiveMonth() {
        List<Order> orderList = orderService.list();

        // 按年月分组订单
        Map<YearMonth, List<Order>> map = orderList.stream()
                .filter(order -> order.getStatus() > OrderStatusType.CANCEL)
                .sorted(Comparator.comparing(Order::getPayTime).reversed())
                .collect(Collectors.groupingBy(order -> YearMonth.of(
                        order.getPayTime().getYear(),
                        order.getPayTime().getMonth()))
                );

        // 转换为VO列表
        List<FirstFiveMonthOrderVO> voList = map.keySet()
                .stream()
                .map(key -> {
                    List<Order> orders = map.get(key);
                    double sum = orders.stream().mapToDouble(order -> order.getTotalFee().doubleValue()).sum();
                    return FirstFiveMonthOrderVO.builder()
                            .month(key)
                            .total(sum)
                            .build();
                }).toList();

        // 计算增长率
        if (!CollectionUtils.isEmpty(voList)) {
            FirstFiveMonthOrderVO first = voList.get(0);
            first.setGrowthRate(0D);

            for (FirstFiveMonthOrderVO current : voList.subList(1, voList.size())) {
                FirstFiveMonthOrderVO previous = voList.get(voList.indexOf(current) - 1);
                double previousAmount = previous.getTotal();
                double currentAmount = current.getTotal();

                // 计算增长率
                double growthRate = Math.round((currentAmount - previousAmount) / previousAmount * 100);

                current.setGrowthRate(growthRate);
            }
        }
        return voList;
    }

    /**
     * 获取总数统计
     * @return 总数统计VO
     */
    @Override
    public TotalNumVO getTotalNum() {
        List<Area> areaList = areaService.list();
        List<User> userList = userService.list();
        List<Activity> activityList = activityService.list();

        return TotalNumVO.builder()
                // 总园区数
                .totalArea(areaList.size())
                // 总商品数
                .totalProduct(activityList.size())
                // 总员工数
                .totalEmployee(userList.size())
                .build();
    }

    /**
     * 获取今日总数统计
     * @return 今日总数统计VO
     */
    @Override
    public TodayTotalNumVO getTodayTotalNum() {
        Long farmId = StpUtil.getSession().getModel("user", User.class).getFarmId();
        // 今天0点
        LocalDateTime time = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);

        List<Order> orderList = orderService.list();

        // 过滤出今天该农场已经付过钱的订单
        List<Order> todayOrderList = orderList.stream()
                .filter(order -> order.getStatus() > OrderStatusType.CANCEL &&
                                order.getPayTime().isAfter(time) &&
                            Objects.equals(order.getFarmId(),farmId)
                        )
                .toList();

        // 计算总销售额
        BigDecimal totalSold = orderList.stream()
                .map(Order::getTotalFee)
                .reduce(new BigDecimal(0), BigDecimal::add);

        // 计算今日销售额
        BigDecimal todaySold = todayOrderList.stream()
                .map(Order::getTotalFee)
                .reduce(new BigDecimal(0), BigDecimal::add);

        return TodayTotalNumVO.builder()
                .totalSold(totalSold)
                .todaySold(todaySold)
                .todayTask(1)
                .totalTask(1)
                .todayOrder(todayOrderList.size())
                .totalOrder(orderList.size())
                .build();
    }

    /**
     * 获取本月用户统计
     * @return 本月用户统计VO
     */
    @Override
    public MonthTotalVO getMonthUser() {
        List<Consumer> consumerList = consumerService.list();
        List<Order> orderList = orderService.list();
        List<Farm> farmList = farmService.list();

        // 获取本月第一天和最后一天
        LocalDateTime now = LocalDateTime.of(LocalDate.now(),LocalTime.MIN);
        LocalDateTime fistDay = now.with(TemporalAdjusters.firstDayOfMonth());
        LocalDateTime lastDay = now.with(TemporalAdjusters.lastDayOfMonth());

        // 过滤本月新增用户
        List<Consumer> monthConsumerList = consumerList.stream()
                .filter(consumer -> {
                    LocalDateTime createTime = consumer.getCreateTime();
                    return createTime.isAfter(fistDay) && createTime.isBefore(lastDay);
                }).toList();

        // 过滤本月支付订单
        List<Order> payOrderList = orderList.stream()
                .filter(order -> {
                    LocalDateTime payTime = order.getPayTime();
                    return order.getStatus() > OrderStatusType.CANCEL && payTime.isAfter(fistDay) && payTime.isBefore(lastDay);
                }).toList();

        // 过滤本月新增农场
        List<Farm> monthFarmList = farmList.stream()
                .filter(farm -> {
                    LocalDateTime createTime = farm.getCreateTime();
                    return createTime.isAfter(fistDay) && createTime.isBefore(lastDay);
                })
                .toList();

        return MonthTotalVO.builder()
                .totalConsumer(consumerList.size())
                .monthConsumer(monthConsumerList.size())
                .totalOrder(orderList.size())
                .monthOrder(payOrderList.size())
                .totalFarm(farmList.size())
                .monthFarm(monthFarmList.size())
                .build();
    }

    /**
     * 获取农场分布情况
     * @return 农场分布VO列表
     */
    @Override
    public List<FarmDistributionVO> getFarmDistribution() {
        List<Farm> farmList = farmService.list();

        // 按省份分组农场
        Map<String, List<Farm>> collect = farmList.stream()
                .collect(Collectors.groupingBy(farm -> farm.getAddress().split(" ")[0]));

        int totalSize = farmList.size();

        // 计算各省份占比
        return collect.keySet()
                .stream()
                .map(key -> {
                    int provinceFarmSize = collect.get(key).size();
                    double value = 100.0 *  provinceFarmSize / totalSize;
                    return FarmDistributionVO.builder()
                            .name(key)
                            .value(value)
                            .build();
                })
                .toList();
    }
}
